<?php
/**
 * 加密解密的算法类。
 * 加密类继承于他，并重写加密部分代码。
 * 解密类继承于他，重写解密部分代码
 * 子类只需要重写加密字符串，其他的不能在子类里面覆盖父类的方法
 * 
 * 	需要重写的方法：
 * 	codeString();
 * 	returnCode()
 *  
 * @author SamPeng
 * @package Safety/Acthcode
 * @link www.sampeng.cn
 * @version $ID:Code.php $Time 2008-11-22 15:28:24 
 * @final 构造函数__cnstruct($_string,$_key);
 * @copyright SamPeng & Comsenz Inc
 */

abstract class Code{
	protected  $string;
	protected $cryptkey;
	protected $key;
	protected $result;
	protected $keya,$keyb,$keyc;
	
	const EXPIRY = 0,CKEY_LENGTH = 4;
	
	/**
	 * 构造函数。定义为final。子类不能重写这个构造函数。但是可以直接继承下去
	 *
	 * @param 任意非中文、非全角字符的任意字符串 $_string
	 * @param 任意字符串 $_key
	 */
	final public function __construct($_string,$_key = ""){
		$this->string = $_string;
		$this->key = $_key;
		$this->getKey();
		$this->codeString();
		$this->arithmetic();
	}
	
	/**
	 * 加密密匙的加密算法
	 */
	final function getKey(){
		$this->key = md5($this->key ? $this->key : "我X你F##@￥@");
		$this->keya = md5(substr($this->key, 0, 16));
		$this->keyb = md5(substr($this->key, 16, 16));
	}	
	/**
	 * 具体的加密或者解密的运算方法
	 */
	final function arithmetic(){
		$string_length = strlen($this->string);
		$this->result = '';
		$box = range(0, 255);
	
		$rndkey = array();
		for($i = 0; $i <= 255; $i++) {
			$rndkey[$i] = ord($this->cryptkey[$i % $this->key_length]);
		}
	
		for($j = $i = 0; $i < 256; $i++) {
			$j = ($j + $box[$i] + $rndkey[$i]) % 256;
			$tmp = $box[$i];
			$box[$i] = $box[$j];
			$box[$j] = $tmp;
		}
	
		for($a = $j = $i = 0; $i < $string_length; $i++) {
			$a = ($a + 1) % 256;
			$j = ($j + $box[$a]) % 256;
			$tmp = $box[$a];
			$box[$a] = $box[$j];
			$box[$j] = $tmp;
			$this->result .= chr(ord($this->string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256]));
		}
	}
	
	abstract protected function codeString();
	abstract protected function returnCode();

}
?>